/*
 * Copyright 2012 Faculty of Informatics - Masaryk University.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cz.muni.fi.pa165.creatures.dao;

import cz.muni.fi.pa165.creatures.dao.impl.CreatureManagerDAOImpl;
import cz.muni.fi.pa165.creatures.model.Creature;
import cz.muni.fi.pa165.creatures.model.CreatureType;
import cz.muni.fi.pa165.creatures.model.Region;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * This class tests methods of {@link CreatureManagerDAOImpl}
 *
 * @author xmiklos1
 */
public class CreatureManagerDAOImplTestCase {

    private static final String PERSISTENCE_UNIT_NAME = "CreaturesTestPU";
    private static EntityManagerFactory factory;
    /**
     * Logger to log all messages to.
     */
    private static final Logger logger = Logger.getLogger(CreatureManagerDAOImplTestCase.class.getName());

    @BeforeClass
    public static void init() {
        factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    }

    @Test
    public void testCreateCreature() {
        log("=== CREATE CREATURE TEST #1 ====================");
        CreatureManagerDAO creatureDAO = new CreatureManagerDAOImpl(factory);
        //RegionManagerDAO regionDAO = new RegionManagerDAOImpl(factory);
        //CreatureTypeManagerDAO creatureTypeDAO = new CreatureTypeManagerDAOImpl(factory);
        
        Creature creature = new Creature("alien X");
        creatureDAO.create(creature);
        Creature creature2 = creatureDAO.get(creature.getId());
        assertEquals(creature, creature2);
        clearDB();

        log("=== CREATE CREATURE TEST #1 ====================");
        Creature creature3 = new Creature("alien X");
        
        //Region region = new Region("Zlty kopec");
        // regionDAO.create(region);
        //creature3.setRegion(region);
        
        //CreatureType creatureType = new CreatureType("Alien", 200);
        // creatureTypeDAO.create(creatureType);
        //creature3.setCreatureType(creatureType);
        
        creatureDAO.create(creature3);
        Creature creature4 = creatureDAO.get(creature3.getId());
        assertEquals(creature4, creature3);
        clearDB();
    }

    @Test
    public void testRemoveCreature() {
        log("=== REMOVE CREATURE TEST =======================");
        CreatureManagerDAOImpl dao = new CreatureManagerDAOImpl(factory);
        Creature creature = new Creature("alien XYZ");
        dao.create(creature);
        dao.remove(creature);
        assertNull(dao.get(creature.getId()));
        clearDB();
    }

    @Test
    public void testUpdateCreature() {
        log("=== UPDATE CREATURE TEST =======================");

        clearDB();
    }

    @Test
    public void testGetCreature() {
        log("=== GET CREATURE TEST ==========================");
        CreatureManagerDAOImpl dao = new CreatureManagerDAOImpl(factory);
        Creature creature = new Creature("alien XZY");
        dao.create(creature);
        Long id = creature.getId();

        clearDB();
    }

    @Test
    public void testGetCountTest() {
        log("=== GET COUNT OF CREATURES TEST ================");
        CreatureManagerDAOImpl dao = new CreatureManagerDAOImpl(factory);
        Creature creature = new Creature("alien XYZ");
        Creature creature2 = new Creature("Mutant 2");
        Creature creature3 = new Creature("dragon 5");

        dao.create(creature);
        dao.create(creature2);
        dao.create(creature3);

        assertEquals(dao.getCount(), 3);

        dao.remove(creature2);

        assertEquals(dao.getCount(), 2);

        clearDB();

        assertEquals(dao.getCount(), 0);
    }

    @AfterClass
    public static void destroy() {
        factory.close();
    }

    public void clearDB() {
        EntityManager em = null;
        try {
            em = factory.createEntityManager();
            Query q = em.createQuery("delete from Creature");
            em.getTransaction().begin();
            int count = q.executeUpdate();
            logger.log(Level.INFO, "number of records deleted: {0}", count);
            em.getTransaction().commit();
        } catch (Exception ex) {
            logger.log(Level.WARNING, "Error while deleting all records from DB", ex.getCause());
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void log(String message) {
        logger.log(Level.INFO, message);
    }
}
